---
title: 从 Next.js 迁移
description: 将现有的 Next.js 项目迁移到 Astro 的提示
sidebar:
  label: Next.js
type: migration
stub: false
framework: Next.js
i18nReady: true
---
import { Steps, LinkCard, CardGrid } from '@astrojs/starlight/components';
import AstroJSXTabs from '~/components/tabs/AstroJSXTabs.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';

这里有一些关键的概念和迁移策略来帮助你开始。可以通过文档其他内容和我们的 [Discord 社区](https://astro.build/chat)来继续完成迁移！

## Next.js 和 Astro 的主要相似之处

Next.js 和 Astro 有一些相似之处，可以帮助你迁移你的项目：

- [`.astro` 文件的语法类似于 JSX](/zh-cn/reference/astro-syntax/#astro-和-jsx-间的差异)。编写 Astro 应该会感觉很熟悉。
- Astro 项目也可以是 SSG 或[具有页面预渲染功能的 SSR](/zh-cn/guides/on-demand-rendering/)。
- Astro 使用基于文件的路由，并[允许特定命名的页面创建动态路由](/zh-cn/guides/routing/#动态路由)。
- Astro 是[基于组件](/zh-cn/basics/astro-components/)的，标签在迁移前后会很相似。
- Astro 具有针对 [React、Preact 和 Solid 的官方集成](/zh-cn/guides/integrations-guide/react/)，因此可以使用现有的 JSX 组件。请注意，在 Astro 中，这些文件**必须**具有 `.jsx` 或 `.tsx` 扩展名。
- Astro 支持[安装 NPM 包](/zh-cn/guides/imports/#npm-包)，包括 React 库。许多现有的依赖将在 Astro 中起作用。

## Next.js 和 Astro 的主要不同之处

当你在 Astro 中重建你的 Next.js 网站时，你会发现一些重要的区别：

- Next.js 是一个 React 单页面应用，使用 `index.js` 作为项目的 root。Astro 是一个多页面的网站，`index.astro` 是你的主页。

- [`.astro` 组件](/zh-cn/basics/astro-components/)：不是作为返回页面模板的导出函数去编写的。相反，会把你的代码分成一个 JavaScript 的"代码栅栏"和一个专门用于生成 HTML 的主体。

- [内容驱动](/zh-cn/concepts/why-astro/#内容驱动)：Astro 旨在展示你的内容，并允许你仅在需要时选择加入交互性。已有的 Next.js 应用程序可能是为重客户端交互性而构建的，并且包含一些使用 `.astro` 组件难以复制、更具挑战性的功能，可能需要高级 Astro 技术来处理，例如仪表盘。

## 转换你的 Next.js 项目

尽管每个项目在迁移的实际过程中都会有些不同，但在从 Next.js 转换到 Astro 时，有一些常见的操作可以参考。

### 创建一个新的 Astro 项目

通过你的包管理器执行命令 `create astro` 来启动 Astro 的 CLI 向导，或从 [Astro Theme Showcase](https://astro.build/themes) 选择一个社区主题。

你可以在 `create astro` 命令中传递一个 `--template` 参数，用我们的官方启动器（如 `docs`、`blog`、`portfolio`）启动一个新的 Astro 项目。或者，你可以[从 GitHub 上任何现有的 Astro 仓库开始一个新项目](/zh-cn/install-and-setup/#通过-cli-向导安装)。

  <PackageManagerTabs>
    <Fragment slot="npm">
    ```shell
    # 启动 Astro CLI 安装向导
    npm create astro@latest

    # 通过官方示例来创建一个新项目
    npm create astro@latest -- --template <example-name>
    ```
    </Fragment>
    <Fragment slot="pnpm">
    ```shell
    # 启动 Astro CLI 安装向导
    pnpm create astro@latest

    # 通过官方示例来创建一个新项目
    pnpm create astro@latest --template <example-name>
    ```
    </Fragment>
    <Fragment slot="yarn">
    ```shell
    # 启动 Astro CLI 安装向导
    yarn create astro@latest

    # 通过官方示例来创建一个新项目
    yarn create astro@latest --template <example-name>
    ```
    </Fragment>
  </PackageManagerTabs>

然后，把现有的 Next 项目文件复制到你的新 Astro 项目中，放在`src`以外的单独文件夹中。

:::tip
访问 https://astro.new 了解官方启动模板的完整列表，以及在 IDX、StackBlitz、CodeSandbox 或 Gitpod 中打开一个新项目的链接。
:::

### 安装集成 (可选)

在将 Next 项目转换为 Astro 时，你可能会发现安装一些 [Astro 可选集成](/zh-cn/guides/integrations-guide/) 是有用的。

- **@astrojs/react**：在你的新 Astro 网站上重用一些现有的 React UI 组件，或者继续用 React 组件来编写。

- **@astrojs/mdx**：将现有的 Next 项目中的 MDX 文件导入，或在新的 Astro 站点中使用 MDX。

### 将源码放在 `src` 目录内

按照 [Astro 的项目结构](/zh-cn/basics/project-structure/)：

<Steps>
1. **保持** Next 的 `public/` 文件夹不动。
   
    Astro 使用 `public/` 目录来存放静态资产，就像 Next 一样。这个文件夹和它的内容都不需要改变。

2. **复制或移动** Next 的其他文件和文件夹（如 `pages`，`styles` 等）到 Astro 的 `src/` 文件夹，当你在重构网站时，遵循 [Astro 的项目结构](/zh-cn/basics/project-structure/)。

    像 Next 一样，Astro 的 `src/pages/` 文件夹是一个特殊的文件夹，用于基于文件的路由。所有其他文件夹都是可选的，你可以以任何方式组织你的 `src/` 文件夹的内容。Astro 项目中其他常见的文件夹包括 `src/layouts/`、`src/components`、`src/styles` 和 `src/scripts`。
</Steps>

### Astro 的配置文件

Astro 在你项目的根目录有一个配置文件，叫做 [`astro.config.mjs`](/zh-cn/guides/configuring-astro/)。这仅用于配置你的 Astro 项目和任何已安装的集成，包括 [SSR 适配器](/zh-cn/guides/deploy/)。

### 提示：将 JSX 文件转换为 `.astro` 文件

这里有一些将 `Next.js` 组件转换为 `.astro` 组件的提示：

1. 使用现有 Next.js 组件函数返回的 JSX 作为你的 HTML 模板的基础。

2. 调整 [Next 或 JSX 语法为 Astro](#参考将-nextjs-语法转换为-astro-语法) 或 HTML 网页标准。例如，这包括 `<Link>`、`<Script>`、`{children}` 和 `className`。

3. 将任何必要的 JavaScript，包括导入语句，移到["代码栅栏"（`---`）](/zh-cn/basics/astro-components/#组件脚本)。注意：[条件渲染内容](/zh-cn/reference/astro-syntax/#动态-html)的 JavaScript 通常直接写在 Astro 的 HTML 模板内。

4. 使用 [`Astro.props`](/zh-cn/reference/api-reference/#props) 来访问之前传递给你的 Next 函数的任何额外 props。

5. 决定是否需要将所有导入的组件都转换为 Astro。安装了官方集成后，[你可以在 Astro 文件中使用现有的 React 组件](/zh-cn/guides/framework-components/)。但是，如果它们不需要交互，你可能需要将它们转换为 `.astro` 组件！

6. 用导入语句或 [`import.meta.glob()`](/zh-cn/guides/imports/#importmetaglob) 代替 `getStaticProps()` 来查询你的本地文件。使用 `fetch()` 来获取外部数据。

参考 [`Next.js` 文件逐步转换的例子](#示例数据请求)。

#### 比较：JSX vs Astro

比较以下 Next 组件和相应的 Astro 组件：

<AstroJSXTabs>
  <Fragment slot="jsx">
    ```jsx title="StarCount.jsx"
    import Header from "./header";
    import Footer from "./footer";
    import "./layout.css";

    export async function getStaticProps() {
        const res = await fetch("https://api.github.com/repos/withastro/astro");
        const json = await res.json();
        return {
            props: { message: json.message, stars: json.stargazers_count || 0 },
        }
    }

    const Component = ({ stars, message }) => {
        
        return (
            <>
                <Header />
                <p style={{
                    backgroundColor: `#f4f4f4`,
                    padding: `1em 1.5em`,
                    textAlign: `center`,
                    marginBottom: `1em`
                }}>Astro has {stars} 🧑‍🚀</p>
                <Footer />
            </>
        )
    }

    export default Component;
    ```
  </Fragment>
  <Fragment slot="astro">
    ```astro title="StarCount.astro"
    ---
    import Header from "./header";
    import Footer from "./footer";
    import "./layout.css";

    const res = await fetch("https://api.github.com/repos/withastro/astro");
    const json = await res.json();
    const message = json.message;
    const stars = json.stargazers_count || 0;
    ---
    <Header />
    <p class="banner">Astro has {stars} 🧑‍🚀</p>
    <Footer />

    <style>
      .banner {
        background-color: #f4f4f4; 
        padding: 1em 1.5em;
        text-align: center;
        margin-bottom: 1em;
      }
    <style>
    ```
  </Fragment>
</AstroJSXTabs>

### 迁移布局文件

你可能会发现从把你的 Next.js 布局和模板转换为 [Astro 布局组件](/zh-cn/basics/layouts/)开始会很有帮助。

Next 有两种不同的方法来创建布局文件，每种方法处理布局的方式都与 Astro 不同：

- `pages` 目录

- [`/app` 目录](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#layouts)

每个 Astro 页面都明确要求有 `<html>`、`<head>` 和 `<body>` 标签，所以在不同的页面中重复使用一个布局文件是很常见的。Astro 使用一个 [`<slot />`](/zh-cn/basics/astro-components/#插槽) 作为页面内容，不需要导入语句。注意标准的 HTML 模板，以及对 `<head>` 的直接访问：

```astro title="src/layouts/Layout.astro"
---
---
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
		<title>Astro</title>
	</head>
	<body>
    <!-- 用你现有的布局模板来包裹插槽元素 -->
		<slot />
	</body>
</html>
```

#### 迁移 Next.js 的 `page` 目录

你的 Next 项目可能有一个 `pages/_document.jsx` 文件，它导入了一些 React 组件来定制你的应用程序的 `<head>`：

```jsx title="pages/_document.jsx"
import Document, { Html, Head, Main, NextScript } from "next/document";

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <link rel="icon" href="/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
```

<Steps>
1. 开发一个新的只返回 JSX 的 Astro 布局文件。

2. 用 `<html>`、`<head>`、`<slot>` 和其他 HTML 标签替换 React 组件。。

    ```astro title="src/layouts/Document.astro"
    <html lang="en">
      <head>
          <link rel="icon" href="/favicon.ico" />
      </head>
      <body>
        <slot/>
      </body>
    </html>
    ```
</Steps>

#### 迁移 Next.js 的 `/app` 目录

Next.js 的 `app/` 目录布局文件是用两个文件创建的：一个 `layout.jsx` 文件用于定制 `<html>` 和 `<body>` 内容，一个 `head.jsx` 文件用于定制 `<head>` 元素内容。

```jsx title="app/layout.jsx"
export default function Layout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
```

```jsx title="app/head.jsx"
export default function Head() {
  return (
    <>
      <title>My Page</title>
    </>
  );
}
```

<Steps>
1. 开发一个新的只返回 JSX 的 Astro 布局文件。

2. 用一个单一的 Astro 布局文件替换这两个文件，其中包含一个页面外壳（`<html>`、`<head>` 和 `<body>` 标签）和一个 `<slot/>`，而不是 React 的 `{children}` props：

    ```astro title="src/layouts/Layout.astro"
    <html lang="en">
      <head>
          <title>My Page</title>
      </head>
      <body>
        <slot/>
      </body>
    </html>
    ```
</Steps>

### 迁移 Pages 和 Posts

在 Next.js 中，你的文章要么在 `/pages`，要么在 `/app/routeName/page.jsx`。

在 Astro 中，除了使用 [内容集合](/zh-cn/guides/content-collections/)，所有的页面内容必须位于 `src/` 中。

#### React 页面

现有的 Next JSX (.js) 页面将需要从 JSX 文件[转换为 .astro 页面](#提示将-jsx-文件转换为-astro-文件)。你不能在 Astro 中使用现有的 JSX 页面文件。

这些 [.astro 页面](/zh-cn/basics/astro-pages/)必须位于 `src/pages/` 内，并将根据其文件路径自动生成页面路由。

#### Markdown 和 MDX 页面

Astro 内置了对 Markdown 的支持和对 MDX 文件的可选整合。你可以复用任何现有的 [Markdown 和 MDX 文件](/zh-cn/guides/markdown-content/)，但它们可能需要对它们的 frontmatter 进行一些调整，比如添加 [Astro 的特殊 `layout` frontmatter 属性](/zh-cn/basics/layouts/#markdown-布局)。你将不再需要为每个 Markdown 生成的路由手动创建页面。这些文件可以放在 `src/pages/` 中，利用文件即路由的优势自动生成。

另外，你可以在 Astro 中使用[内容集合](/zh-cn/guides/content-collections/)来存储和管理你的内容。你将自己检索内容，并[动态生成这些页面](/zh-cn/guides/content-collections/#从内容生成路由)。

### 迁移测试

由于 Astro 输出的是原始 HTML，所以可以使用构建步骤的输出来编写端到端的测试。如果你已经能够匹配你的 Next 网站的标记，以前写的任何端到端测试都可能开箱即用。测试库，如 Jest 和 React 测试库，可以被导入并用于 Astro 测试你的 React 组件。

参见 Astro 的[测试指南](/zh-cn/guides/testing/)了解更多。

## 参考：将 Next.js 语法转换为 Astro 语法

### 链接

将任何 Next `<Link to="">`，`<NavLink>` 等组件转换成 HTML `<a href="">` 标签。

```astro del={1} ins={2}
<Link to="/blog">Blog</Link>
<a href="/blog">Blog</a>
```

Astro 没有为链接使用任何特殊的组件，但我们欢迎你建立你自己的 `<Link>` 组件。然后你可以像使用其他组件一样导入和使用这个 `<Link>`。

```astro title="src/components/Link.astro"
---
const { to } = Astro.props;
---
<a href={to}><slot /></a>
```

### 导入

更新任何[文件导入](/zh-cn/guides/imports/)以准确引用相对文件路径。这可以通过 [import aliases](/zh-cn/guides/typescript/#导入别名) 来完成，或者通过写出相对路径的全称。

请注意，".astro "和其他一些文件类型必须以其完整的文件扩展名导入。

```astro title="src/pages/authors/Fred.astro"
---
import Card from "../../components/Card.astro";
---
<Card />
```

### 转换 Next 的 Children Props 到 Astro

将任何 `{children}` 的实例转换为 Astro 的 `<slot />`。Astro 不需要接收 `{children}` 作为一个函数 prop，并会自动在 `<slot />` 中渲染 child 内容。

```astro title="src/components/MyComponent.astro" del={3-9} ins={11-13}
---
---
export default function MyComponent(props) { 
    return (
      <div>
        {props.children}
      </div>
    );  
}

<div>
  <slot />
</div>
```

可以使用[命名插槽](/zh-cn/basics/astro-components/#命名插槽)将有多个子组件的 React 组件迁移到 Astro 组件。

参考更多关于 [Astro 中具体的 `<slot />` 用法](/zh-cn/basics/astro-components/#插槽)。

### 转换 Next 的数据获取到 Astro

将 `getStaticProps()` 中任何实例转换为 `import.meta.glob()` 或 `getCollection()`/`getEntry()`，以便访问项目中其他文件的数据。为了[获取远程数据](/zh-cn/guides/data-fetching/)，使用 `fetch()`。

这些数据请求是在 Astro 组件的 frontmatter 中执行的，并使用 top-level await。

```astro title="src/pages/index.astro"
---
import { getCollection } from 'astro:content';

// 获取所有 `src/content/blog/` 的入口
const allBlogPosts = await getCollection('blog');

// 获取所有 `src/pages/posts/` 的入口
const allPosts = Object.values(import.meta.glob('../pages/posts/*.md', { eager: true }));

const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---
```

查看更多关于[用 `import.meta.glob()` 导入本地文件](/zh-cn/guides/imports/#importmetaglob)，[使用 Collections API 查询](/zh-cn/guides/content-collections/#查询集合)或[获取远程数据](/zh-cn/guides/data-fetching/)。

### 转换 Next 的样式到 Astro

你可能需要用 Astro 中其他可用的 CSS 选项来替换任何 [CSS-in-JS 库](https://github.com/withastro/astro/issues/4432)（例如 styled-components）。

如果有必要，将任何内联样式对象（`style={{ fontWeight: "bold" }}`）转换成内联 HTML 样式属性（`style="font-weight:bold;"`）。或者，使用 [Astro `<style>`标签](/zh-cn/guides/styling/#在-astro-进行设计)实现 scoped CSS styles。

```astro title="src/components/Card.astro" del={1} ins={2}
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div>
<div style="background-color: #f4f4f4; padding: 1em;">{message}</div>
```

在安装了 [Tailwind Vite 插件](/zh-cn/guides/styling/#tailwind)之后，就支持 Tailwind。不需要对你现有的 Tailwind 代码进行任何修改！

查看更多关于[在 Astro 中设计样式](/zh-cn/guides/styling/) 的信息。

### 转换 Next 的 图像插件到 Astro
 
根据情况在你的 React 组件中将任何 Next 的 `<Image />` 组件转换为 [Astro 自己的图像集成组件](/zh-cn/guides/images/)或者转化成[标准的 HTML `<img>` / JSX `<img />` 标签](/zh-cn/guides/images/#ui-框架组件中的图像)。

Astro 的 `<Image />` 组件只能在 `.astro` 和 `.mdx` 文件中工作。查看该组件可用的[完整组件属性列表](/zh-cn/reference/modules/astro-assets/#image-属性)，并注意它与 Next 的属性有一些不同。

```astro title="src/pages/index.astro"
---
import { Image } from 'astro:assets';
import rocket from '../assets/rocket.png';
---
<Image src={rocket} alt="太空中的火箭飞船。" />
<img src={rocket.src} alt="太空中的火箭飞船。">
```

在 React (`.jsx`) 组件中，使用标准的 JSX 的图片语法（`<img />`）。Astro 不会优化这些图片，但你也可以安装和使用 NPM 包以提升灵活性。

你可以在图像指南中了解更多关于[在 Astro 中使用图像](/zh-cn/guides/images/)的信息。

## 示例：数据请求

下面是一个 Next.js Pokédex 数据获取转换为 Astro 的例子。
    
`pages/index.js` 使用 [REST PokéAPI](https://pokeapi.co/) 获取并显示前 151 个神奇宝贝的列表。

下面是如何在 `src/pages/index.astro` 中重新创建，将 `getStaticProps()` 替换为 `fetch()`。

<Steps>
1. 定义要返回的 JSX。

    ```jsx title="pages/index.js" {6-18}
    import Link from 'next/link'
    import styles from '../styles/poke-list.module.css';

    export default function Home({ pokemons }) {
        return (
            <>
                <ul className={`plain-list ${styles.pokeList}`}>
                    {pokemons.map((pokemon) => (
                        <li className={styles.pokemonListItem} key={pokemon.name}>
                            <Link className={styles.pokemonContainer} as={`/pokemon/${pokemon.name}`} href="/pokemon/[name]">
                                <p className={styles.pokemonId}>No. {pokemon.id}</p>
                                <img className={styles.pokemonImage} src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemon.id}.png`} alt={`${pokemon.name} picture`}></img>
                                <h2 className={styles.pokemonName}>{pokemon.name}</h2>
                            </Link>
                        </li>
                    ))}
                </ul>
            </>
        )
    }

    export const getStaticProps = async () => {
        const res = await fetch("https://pokeapi.co/api/v2/pokemon?limit=151")
        const resJson = await res.json();
        const pokemons = resJson.results.map(pokemon => {
            const name = pokemon.name;
            // https://pokeapi.co/api/v2/pokemon/1/
            const url = pokemon.url;
            const id = url.split("/")[url.split("/").length - 2];
            return {
                name,
                url,
                id
            }
        });
        return {
            props: {
                pokemons,
            },
        }
    }
    ```

2. 创建 `src/pages/index.astro`

    使用 Next 函数的返回值。将任何 Next 或 React 语法转换成 Astro，包括改变任何 [HTML 全局属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes)的大小写。

    注意：

    - `.map` 就已经可以了

    - `className` 变成 `class`。

    - `<Link>` 变成 `<a>`。

    - `<> </>` 在 Astro 模板设计中是不需要的。

    - `key` 是一个 React 属性而不是 `li` 标签的一个属性。

    ```astro title="src/pages/index.astro" "class" "</a>" "<a"
    ---
    ---
    <ul class="plain-list pokeList">
        {pokemons.map((pokemon) => (
            <li class="pokemonListItem">
                <a class="pokemonContainer" href={`/pokemon/${pokemon.name}`}>
                    <p class="pokemonId">No. {pokemon.id}</p>
                    <img class="pokemonImage" src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemon.id}.png`} alt={`${pokemon.name} picture`}/>
                    <h2 class="pokemonName">{pokemon.name}</h2>
                </a>
            </li>
        ))}
    </ul>
    ```

3. 添加任何需要的 imports, props, 和 JavaScript

    注意：

    - 不再需要 `getStaticProps` 函数。来自 API 的数据直接在代码栅栏中被获取。
    - 一个 `<Layout>` 组件被导入并包裹了页面模板。

    ```astro ins={2,4-16,19,31} title="src/pages/index.astro"
    ---
    import Layout from '../layouts/layout.astro';

    const res = await fetch("https://pokeapi.co/api/v2/pokemon?limit=151");
    const resJson = await res.json();
    const pokemons = resJson.results.map(pokemon => {
        const name = pokemon.name;
        // https://pokeapi.co/api/v2/pokemon/1/
        const url = pokemon.url;
        const id = url.split("/")[url.split("/").length - 2];
        return {
            name,
            url,
            id
        }
    });
    ---

    <Layout>
      <ul class="plain-list pokeList">
          {pokemons.map((pokemon) => (
              <li class="pokemonListItem" key={pokemon.name}>
                  <a class="pokemonContainer" href={`/pokemon/${pokemon.name}`}>
                      <p class="pokemonId">No. {pokemon.id}</p>
                      <img class="pokemonImage" src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${pokemon.id}.png`} alt={`${pokemon.name} picture`}/>
                      <h2 class="pokemonName">{pokemon.name}</h2>
                  </a>
              </li>
          ))}
      </ul>
    </Layout>
    ```
</Steps>

## 社区资源

<CardGrid>
  <LinkCard title="我们为何转向 Astro（以及为何你可能会感兴趣）" href="https://www.datocms.com/blog/why-we-switched-to-astro" />
  <LinkCard title="从 Next.js 迁移到 Astro" href="https://johnzanussi.com/posts/nextjs-to-astro-migration" />
  <LinkCard title="从 NextJS 到 Astro" href="https://vanntile.com/blog/next-to-astro" />
  <LinkCard title="转换 Next.js 为 Astro" href="https://ericclemmons.com/blog/converting-nextjs-to-astro" />
  <LinkCard title="迁移到 Astro (从 Next.js)" href="https://www.raygesualdo.com/posts/migrating-to-astro-the-beginning/" />
  <LinkCard title="Astro.js 作为 Next.js 的替代方案" href="https://www.railyard.works/blog/astro-as-alternative-to-next" />
  <LinkCard title="为什么我把网站从 Next.js 迁移到了 Astro
" href="https://praveenjuge.com/blog/why-i-switched-my-website-from-nextjs-to-astro/" />
  <LinkCard title="NextJS 到 Astro：更多控制 = 更快的站点" href="https://www.youtube.com/watch?v=PSzCtdM20Fc" />
  <LinkCard title="Astro 如何让我的网站提速百倍" href="https://www.youtube.com/watch?v=cOxA3kMYtkM" />
</CardGrid>

:::note[有想要分享的资源吗？]
如果你找到（或制作）了一个关于将 Next.js 网站转换为 Astro 的有用的视频或博客文章，请将其 [添加到这个列表中](https://github.com/withastro/docs/edit/main/src/content/docs/en/guides/migrate-to-astro/from-nextjs.mdx)！
:::


